package com.hp.bon.sgw.wh.processor;

import static com.hp.bon.sgw.Constants.LOG;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Iterator;

import javax.xml.stream.XMLInputFactory;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.bean.SysParamBean;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.ChannelServer;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.processor.Processor;
import com.hp.bon.sgw.core.route.RouteInfo;
import com.hp.bon.sgw.domain.Node;
import com.hp.bon.sgw.service.ConfigService;
import com.hp.bon.sgw.wh.bean.NetListQueryPara;
import com.hp.bon.sgw.wh.channel.TMallChannel;

public class NetListQueryNewProcessor extends Processor {
	private static final Logger logger = LoggerFactory.getLogger(TMallChannel.class);
	static XMLInputFactory inputFactory = XMLInputFactory.newInstance();
	@Autowired
	private ConfigService configService;
	@Override
	public int process(CallParam callParam) {
		XmlMessage reqM = (XmlMessage) callParam.getRequest();
		XmlMessage ackM = new XmlMessage(false);
		ackM.setRC("0");
		ackM.setDS("");
		ackM.setSIG("");
		
		String reqXML = "";
		try {
			reqXML = convertReq(reqM);
		} catch (Exception e) {
			LOG.warn("Invalid request DATA format ,not valid xml: ", e);
			ackM.setRC(String.valueOf(Constants.ResultCode.UNKNOW_TAG));
			ackM.setDS("Invalid request DATA format ,not valid xml: " + e.toString());
		}
		
		//RouteInfo r = ChannelServer.findRoute(callParam.getServiceContextId(), callParam.getSessionId());
		//RouteInfo r = ChannelServer.findRoute(callParam.getServiceContextId());
		//LOG.debug("################################## 2.2 process(): r.curNode=" + r.curNode);
		//callParam.setToNode(r.curNode);
		
		Node node = ChannelServer.routeMap.get(callParam.getServiceContextId()).curNode;
		callParam.setToNode(node);
		String url = callParam.getToNode().getServerUrl();
		PostMethod post = new PostMethod(url);
		boolean sendOK = false;
		String resp = "";
		
		try {
			RequestEntity requestEntity = new StringRequestEntity(reqXML, "text/xml", "UTF-8");
			post.setRequestEntity(requestEntity);
			HttpClient client = new HttpClient();
			int timeout = configService.getIntValue(SysParamBean.KEY_AGREEMENT_SCSP_MSG_Timeout, 60);
			client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout*1000);
			client.executeMethod(post);
			resp = post.getResponseBodyAsString();
			sendOK = true;
		} catch (UnsupportedEncodingException e) {
			LOG.warn("unsupported encoding of request.", e);
			ackM.setRC(String.valueOf(Constants.ResultCode.TYPE_ERROR));
			ackM.setDS("unsupported encoding of request.");
		} catch (HttpException e) {
			LOG.warn("send ws request to BON error.", e);
			ackM.setRC(String.valueOf(Constants.ResultCode.BON_ERROR));
			ackM.setDS("send ws request to BON error.");
		} catch (IOException e) {
			LOG.warn("send ws request to BON time out: ", e);
			ackM.setRC(String.valueOf(Constants.ResultCode.BON_TIMEOUT));
			ackM.setDS("send ws request to BON time out: ");
		} catch (Exception e){
			LOG.warn("send ws request to BON error.", e);
			ackM.setRC(String.valueOf(Constants.ResultCode.BON_ERROR));
			ackM.setDS("send ws request to BON error.");
		}
		
		//解析返回串
		String data = "";
		if(sendOK){
			try {
				data = parseNetListReturn(resp);
			} catch (Exception e) {
				LOG.warn("response from BON is valid.", e);
				ackM.setRC(String.valueOf(Constants.ResultCode.BON_ERROR));
				ackM.setDS("response from BON is valid.");
			}
		}
		
		ackM.setDATA(data);
		ackM.setMID(reqM.getMID());
		ackM.setRTT(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(System.currentTimeMillis()));
		callParam.setResponse(ackM);
		this.proccessResponse(callParam);
		
		return 0;
	}


	public int proccessResponse(CallParam callParam) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("OcsSessionCtrlProcessor endProcess");
		}
		callParam.getAsynHandler().onCallResult(callParam);
		return 0;
	}
	
	/*private static ISvr getClient(String serverURL) {
		URL wsdlURL;
		QName serviceQname = new QName("http://ws.hquery.ailk.com/", "ISvrService");
		String wsdl = "DetailNew2.wsdl";
		try {
			wsdlURL = Thread.currentThread().getContextClassLoader().getResource(wsdl);
			if (wsdlURL == null) {
				throw new RuntimeException("cant' find wsdl file " + wsdl);
			}
		} catch (Exception e) {
			throw new RuntimeException("bad wsdl url:" + e);
		}
		ISvrService sgwServiceClient = new ISvrService(wsdlURL, serviceQname);
		ISvr client = sgwServiceClient.getISvrPort();
		Map<String, Object> ctx = ((BindingProvider) client).getRequestContext();
		ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, serverURL);

		return client;
	}
	
	private static SGWService getSGWServiceClient(String serverURL) {
		URL wsdlURL;
		QName serviceQname = new QName("http://www.chinatelecom.cn/SGW/SOAP", "SGWService");
		String wsdl = "All_SGW_WEBSERVICE.wsdl";
		try {
			wsdlURL = Thread.currentThread().getContextClassLoader().getResource(wsdl);
			if (wsdlURL == null) {
				throw new RuntimeException("cant' find wsdl file " + wsdl);
			}
		} catch (Exception e) {
			throw new RuntimeException("bad wsdl url:" + e);
		}
		SGWService_Service sgwServiceClient = new SGWService_Service(wsdlURL, serviceQname);
		SGWService client = sgwServiceClient.getSGWServiceSOAP();
		Map<String, Object> ctx = ((BindingProvider) client).getRequestContext();
		ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, serverURL);
		// ctx.put(BindingProviderProperties.REQUEST_TIMEOUT, 30000);
		// ctx.put(BindingProviderProperties.CONNECT_TIMEOUT, 10000);

		return client;
	}
	
	private void callJAXWS(){
		//String url = callParam.getToNode().getServerUrl();
		String url = "http://133.0.128.33:9080/hqws_hb/hquery";
		ISvr service = getClient(url);

		ListQueryPara listQueryPara = new ListQueryPara();
		listQueryPara.setQuerytype("1");
		listQueryPara.setQueryfrom("209");
		listQueryPara.setServid("19052929130");
		listQueryPara.setSelectType("1");
		listQueryPara.setBeginDate("20140412000000");
		listQueryPara.setEndDate("20140431235959");
		listQueryPara.setGetFlag("0");
		listQueryPara.setAreaCode("1001");
		
		String param = listQueryPara.convertPara();
		param = "<![CDATA[<query type='1' from='209'><param name='acctId'></param><param name='servid'>19052929130</param><param name='selectType'>1</param><param name='beginDate'>20140412000000</param><param name='endDate'>20140431235959</param><param name='getFlag'>0</param><param name='areaCode'>1001</param><start name='queryBatchStart'></start><start name='queryBatch'></start></query>]]>";
		Result ack = service.hquery(param);
		//System.out.println("ack " + ack.getRC() + " hint :" + ack.getDS() + " data :" + ack.getDATA());
		System.out.println(ack.getResult());
	}*/
	
	private String convertReq(XmlMessage reqM) throws Exception{
		/*StringBuffer reqXML = new StringBuffer();
		reqXML.append("<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/\'  ");
		reqXML.append("xmlns:ws='http://ws.hquery.ailk.com/'>");
		reqXML.append("<soapenv:Header/>");
		reqXML.append(" <soapenv:Body>");
		reqXML.append("<ws:hquery> <param>");
		reqXML.append("<![CDATA[<query type='1' from='209'><param name='acctId'></param><param name='servid'>19052929130</param><param name='selectType'>1</param><param name='beginDate'>20140412000000</param><param name='endDate'>20140431235959</param><param name='getFlag'>0</param><param name='areaCode'>1001</param><start name='queryBatchStart'></start><start name='queryBatch'></start></query>]]>");
		reqXML.append("	</param></ws:hquery></soapenv:Body></soapenv:Envelope>");*/
		
		NetListQueryPara para = parseReqData(reqM.getDATA());
		String paraXML = para.convertPara();
		
		StringBuffer reqXML = new StringBuffer();
		reqXML.append("<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/\'  ");
		reqXML.append("xmlns:ws='http://ws.hquery.ailk.com/'>");
		reqXML.append("<soapenv:Header/>");
		reqXML.append("<soapenv:Body>");
		reqXML.append("<ws:hquery> <param>");
		reqXML.append(paraXML);
		reqXML.append("</param></ws:hquery></soapenv:Body></soapenv:Envelope>");
		return reqXML.toString();
	}
	
	private NetListQueryPara parseReqData(String reqData) throws Exception{
		NetListQueryPara para = new NetListQueryPara();
		//reqData.replace("<![CDATA[", "");
		//reqData.replace("]]>", "");
		Document doc = DocumentHelper.parseText(reqData);
		Element root = doc.getRootElement();
		@SuppressWarnings("rawtypes")
		Iterator it = root.elementIterator();
		while(it.hasNext()){
			Element node = (Element)it.next();
			String name = node.getName();
			String value = node.getStringValue();
			if("querytype".equals(name)){
				para.setQuerytype(value);
			}else if("queryfrom".equals(name)){
				para.setQueryfrom(value);
			}else if("acctId".equals(name)){
				para.setAcctId(value);
			}else if("servid".equals(name)){
				para.setServid(value);
			}else if("selectType".equals(name)){
				para.setSelectType(value);
			}else if("beginDate".equals(name)){
				para.setBeginDate(value);
			}else if("endDate".equals(name)){
				para.setEndDate(value);
			}else if("getFlag".equals(name)){
				para.setGetFlag(value);
			}else if("areaCode".equals(name)){
				para.setAreaCode(value);
			}else if("queryBatchStart".equals(name)){
				para.setQueryBatchStart(value);
			}else if("queryBatch".equals(name)){
				para.setQueryBatch(value);
			}
		}
		return para;
	}

	private String parseNetListReturn(String representation) throws Exception {
		StringBuffer data = new StringBuffer();
		Document doc = DocumentHelper.parseText(representation);
		Element root = doc.getRootElement();
		Element returnE = root.element("Body").element("hqueryResponse").element("return");
		returnE.setName("Service_Information");
		String xmlStr = returnE.asXML();
    	data.append(xmlStr);
		return data.toString();
	}

	public void setConfigService(ConfigService configService) {
		this.configService = configService;
	}

	@Override
	public int endProcess(CallParam arg0) {
		// TODO Auto-generated method stub
		return 0;
	}


	
	
}
